import type {
  HostnameConvertRule,
  PlatformElementConfig,
  PlatformType,
  PlatformTypeValue,
  RedirectRule,
} from '../interfaces'
import { getCurrentHostname } from './app'
import { logger } from './logger_config'
import { preprocessElementConfigs } from './personalization'
import { FIVE_ONE_CTO_PAGE_ELEMENTS } from './personalization/51_cto'
import { BAI_DU_PAGE_ELEMENTS } from './personalization/bai_du'
import { BIAN_PAGE_ELEMENTS } from './personalization/bian'
import { BILIBILI_PAGE_ELEMENTS } from './personalization/bilibili'
import { BILIBILI_VIDEO_PAGE_ELEMENTS } from './personalization/bilibili_video'
import { BING_PAGE_ELEMENTS } from './personalization/bing'
import { CSDN_PAGE_ELEMENTS } from './personalization/csdn'
import { GITEE_PAGE_ELEMENTS } from './personalization/gitee'
import { GITHUB_PAGE_ELEMENTS } from './personalization/github'
import { GOOGLE_PAGE_ELEMENTS } from './personalization/google'
import { GREASY_FORK_PAGE_ELEMENTS } from './personalization/greasy_fork'
import { ICONFONT_PAGE_ELEMENTS } from './personalization/iconfont'
import { JIAN_SHU_PAGE_ELEMENTS } from './personalization/jian_shu'
import { JUE_JIN_PAGE_ELEMENTS } from './personalization/jue_jin'
import { SO_PAGE_ELEMENTS } from './personalization/so'
import { SOGOU_PAGE_ELEMENTS } from './personalization/sogou'
import { ZHI_HU_PAGE_ELEMENTS } from './personalization/zhi_hu'
import { ZHI_HU_QUESTION_PAGE_ELEMENTS } from './personalization/zhi_hu_question'

// CSDN 博客
const CSDN_HOSTNAME: string = 'blog.csdn.net'
// 百度搜索
export const BAI_DU_BASE_URL: string = 'https://www.baidu.com'
// 谷歌搜索
export const GOOGLE_HOSTNAME: string = 'www.google.com'
export const GOOGLE_HOSTNAME_HK: string = 'www.google.com.hk'
// 必应搜素
const BING_HOSTNAME: string = 'cn.bing.com'
const BING_HOSTNAME_INTERNATIONAL: string = 'www.bing.com'
// 搜狗搜索
const SO_GOU_HOSTNAME: string = 'www.sogou.com'
export const SO_GOU_WEIXIN_HOSTNAME: string = 'weixin.sogou.com'
export const SO_GOU_VIDEO_HOSTNAME: string = 'v.sogou.com'
export const SO_GOU_KNOWLEDGE_HOSTNAME: string = 'zhishi.sogou.com'
export const SO_GOU_ENCYCLOPEDIA_HOSTNAME: string = 'mingyi.sogou.com'
// 360 搜索
const SO_HOSTNAME: string = 'www.so.com'
export const SO_AI_HOSTNAME: string = 'www.n.cn'
export const SO_VIDEO_HOSTNAME: string = 'tv.360kan.com'
export const SO_NEWS_HOSTNAME: string = 'news.so.com'
export const SO_WEN_KU_HOSTNAME: string = 'wenku.so.com'
export const SO_ENCYCLOPEDIA_HOSTNAME: string = 'baike.so.com'

// 支持的网站域名
export const SUPPORTED_PLATFORMS: any = {
  CSDN: CSDN_HOSTNAME,
  ZHI_HU: 'zhuanlan.zhihu.com',
  JIAN_SHU: 'www.jianshu.com',
  JUE_JIN: 'juejin.cn',
  FIVE_ONE_CTO: 'blog.51cto.com',
  ZHI_HU_QUESTION: 'www.zhihu.com',
  GREASY_FORK: 'greasyfork.org',
  BAI_DU: 'www.baidu.com',
  GOOGLE: GOOGLE_HOSTNAME,
  BING: BING_HOSTNAME,
  SO_GOU: SO_GOU_HOSTNAME,
  SO: SO_HOSTNAME,
  BILIBILI: 'www.bilibili.com',
  BILIBILI_VIDEO: 'www.bilibili.com/video',
  ICONFONT: 'www.iconfont.cn',
  BIAN: 'pic.netbian.com',
  GITEE: 'gitee.com',
  GITHUB: 'github.com',
}

/**
 * 平台分类
 */
export enum PlatformCategoryType {
  BLOG = 'blog',
  SEARCH_ENGINE = 'searchEngine',
  TIE_BAR = 'tieBar',
  VIDEO = 'video',
  IMAGE = 'image',
  CODE = 'code',
  OTHER = 'other',
}
export const PLATFORM_CATEGORY: Record<PlatformTypeValue, PlatformCategoryType[]> = {
  // 博客
  [SUPPORTED_PLATFORMS.CSDN]: [PlatformCategoryType.BLOG],
  [SUPPORTED_PLATFORMS.ZHI_HU]: [PlatformCategoryType.BLOG],
  [SUPPORTED_PLATFORMS.JIAN_SHU]: [PlatformCategoryType.BLOG],
  [SUPPORTED_PLATFORMS.JUE_JIN]: [PlatformCategoryType.BLOG],
  [SUPPORTED_PLATFORMS.FIVE_ONE_CTO]: [PlatformCategoryType.BLOG],
  // 搜索引擎
  [SUPPORTED_PLATFORMS.BAI_DU]: [PlatformCategoryType.SEARCH_ENGINE],
  [SUPPORTED_PLATFORMS.GOOGLE]: [PlatformCategoryType.SEARCH_ENGINE],
  [SUPPORTED_PLATFORMS.BING]: [PlatformCategoryType.SEARCH_ENGINE],
  [SUPPORTED_PLATFORMS.SO_GOU]: [PlatformCategoryType.SEARCH_ENGINE],
  [SUPPORTED_PLATFORMS.SO]: [PlatformCategoryType.SEARCH_ENGINE],
  // 贴吧
  [SUPPORTED_PLATFORMS.ZHI_HU_QUESTION]: [PlatformCategoryType.TIE_BAR],
  // 视频
  [SUPPORTED_PLATFORMS.BILIBILI]: [PlatformCategoryType.BLOG],
  [SUPPORTED_PLATFORMS.BILIBILI_VIDEO]: [PlatformCategoryType.VIDEO],
  // 图片
  [SUPPORTED_PLATFORMS.ICONFONT]: [PlatformCategoryType.IMAGE],
  [SUPPORTED_PLATFORMS.BIAN]: [PlatformCategoryType.IMAGE],
  // 代码
  [SUPPORTED_PLATFORMS.GITEE]: [PlatformCategoryType.CODE, PlatformCategoryType.BLOG],
  // 其他
  [SUPPORTED_PLATFORMS.GREASY_FORK]: [PlatformCategoryType.OTHER],
}

/**
 * 判断平台是否属于指定分类
 */
export function isPlatformCategoryType(platform: PlatformTypeValue, type: PlatformCategoryType): boolean {
  return (PLATFORM_CATEGORY[platform] || []).includes(type)
}

/**
 * 处理后的页面元素配置
 */
export const PROCESS_PAGE_ELEMENTS: Record<PlatformTypeValue, Record<string, PlatformElementConfig>> = {
  [SUPPORTED_PLATFORMS.CSDN]: preprocessElementConfigs(CSDN_PAGE_ELEMENTS),
  [SUPPORTED_PLATFORMS.ZHI_HU]: preprocessElementConfigs(ZHI_HU_PAGE_ELEMENTS),
  [SUPPORTED_PLATFORMS.JUE_JIN]: preprocessElementConfigs(JUE_JIN_PAGE_ELEMENTS),
  [SUPPORTED_PLATFORMS.JIAN_SHU]: preprocessElementConfigs(JIAN_SHU_PAGE_ELEMENTS),
  [SUPPORTED_PLATFORMS.BAI_DU]: preprocessElementConfigs(BAI_DU_PAGE_ELEMENTS),
  [SUPPORTED_PLATFORMS.FIVE_ONE_CTO]: preprocessElementConfigs(FIVE_ONE_CTO_PAGE_ELEMENTS),
  [SUPPORTED_PLATFORMS.ZHI_HU_QUESTION]: preprocessElementConfigs(ZHI_HU_QUESTION_PAGE_ELEMENTS),
  [SUPPORTED_PLATFORMS.GREASY_FORK]: preprocessElementConfigs(GREASY_FORK_PAGE_ELEMENTS),
  [SUPPORTED_PLATFORMS.BILIBILI]: preprocessElementConfigs(BILIBILI_PAGE_ELEMENTS),
  [SUPPORTED_PLATFORMS.BILIBILI_VIDEO]: preprocessElementConfigs(BILIBILI_VIDEO_PAGE_ELEMENTS),
}

/**
 * 页面元素配置
 */
export const PAGE_ELEMENTS: Record<PlatformTypeValue, Record<string, PlatformElementConfig>> = {
  [SUPPORTED_PLATFORMS.CSDN]: CSDN_PAGE_ELEMENTS,
  [SUPPORTED_PLATFORMS.ZHI_HU]: ZHI_HU_PAGE_ELEMENTS,
  [SUPPORTED_PLATFORMS.JUE_JIN]: JUE_JIN_PAGE_ELEMENTS,
  [SUPPORTED_PLATFORMS.JIAN_SHU]: JIAN_SHU_PAGE_ELEMENTS,
  [SUPPORTED_PLATFORMS.BAI_DU]: BAI_DU_PAGE_ELEMENTS,
  [SUPPORTED_PLATFORMS.GOOGLE]: GOOGLE_PAGE_ELEMENTS,
  [SUPPORTED_PLATFORMS.BING]: BING_PAGE_ELEMENTS,
  [SUPPORTED_PLATFORMS.SO_GOU]: SOGOU_PAGE_ELEMENTS,
  [SUPPORTED_PLATFORMS.SO]: SO_PAGE_ELEMENTS,
  [SUPPORTED_PLATFORMS.FIVE_ONE_CTO]: FIVE_ONE_CTO_PAGE_ELEMENTS,
  [SUPPORTED_PLATFORMS.ZHI_HU_QUESTION]: ZHI_HU_QUESTION_PAGE_ELEMENTS,
  [SUPPORTED_PLATFORMS.GREASY_FORK]: GREASY_FORK_PAGE_ELEMENTS,
  [SUPPORTED_PLATFORMS.ICONFONT]: ICONFONT_PAGE_ELEMENTS,
  [SUPPORTED_PLATFORMS.BIAN]: BIAN_PAGE_ELEMENTS,
  [SUPPORTED_PLATFORMS.BILIBILI]: BILIBILI_PAGE_ELEMENTS,
  [SUPPORTED_PLATFORMS.BILIBILI_VIDEO]: BILIBILI_VIDEO_PAGE_ELEMENTS,
  [SUPPORTED_PLATFORMS.GITEE]: GITEE_PAGE_ELEMENTS,
  [SUPPORTED_PLATFORMS.GITHUB]: GITHUB_PAGE_ELEMENTS,
}

/**
 * 重定向规则
 */
export const REDIRECT_RULES: RedirectRule[] = [
  {
    platform: SUPPORTED_PLATFORMS.ZHI_HU,
    domain: 'link.zhihu.com',
    paramName: 'target',
  },
  {
    platform: SUPPORTED_PLATFORMS.CSDN,
    domain: 'link.csdn.net',
    paramName: 'target',
  },
  {
    platform: SUPPORTED_PLATFORMS.JUE_JIN,
    domain: 'link.juejin.cn',
    paramName: 'target',
  },
  {
    platform: SUPPORTED_PLATFORMS.ZHI_HU,
    domain: 'link.zhihu.com',
    paramName: 'target',
  },
  {
    platform: SUPPORTED_PLATFORMS.JIAN_SHU,
    domain: 'links.jianshu.com',
    paramName: 'to',
  },
  {
    platform: SUPPORTED_PLATFORMS.FIVE_ONE_CTO,
    domain: 'blog.51cto.com',
    paramName: 'transfer',
  },
  {
    platform: SUPPORTED_PLATFORMS.GITEE,
    domain: 'gitee.com',
    paramName: 'target',
  },
]

/**
 * 获取当前平台域名值
 */
export function getPlatformValue(hostname: string): string | undefined {
  const platformType = (Object.keys(SUPPORTED_PLATFORMS) as PlatformType[]).find(
    key => SUPPORTED_PLATFORMS[key] === hostname,
  )

  if (!platformType)
    logger.warn(`未找到域名配置：${hostname}`)

  return platformType ? SUPPORTED_PLATFORMS[platformType] : undefined
}

/**
 * 域名转换规则配置
 */
export const HOSTNAME_CONVERT_RULES: HostnameConvertRule[] = [
  // 来源：https://blog.csdn.net/zkw54334?type=blog
  {
    matchMethod: 'endsWith',
    matchValue: CSDN_HOSTNAME,
    convertTo: CSDN_HOSTNAME,
  },
  // 谷歌搜索
  {
    matchMethod: 'equals',
    matchValue: GOOGLE_HOSTNAME_HK,
    convertTo: GOOGLE_HOSTNAME,
  },
  // 必应搜索
  {
    matchMethod: 'equals',
    matchValue: BING_HOSTNAME_INTERNATIONAL,
    convertTo: BING_HOSTNAME,
  },
  // 搜狗搜索
  {
    matchMethod: 'equals',
    matchValue: SO_GOU_WEIXIN_HOSTNAME,
    convertTo: SO_GOU_HOSTNAME,
  },
  {
    matchMethod: 'equals',
    matchValue: SO_GOU_VIDEO_HOSTNAME,
    convertTo: SO_GOU_HOSTNAME,
  },
  {
    matchMethod: 'equals',
    matchValue: SO_GOU_KNOWLEDGE_HOSTNAME,
    convertTo: SO_GOU_HOSTNAME,
  },
  {
    matchMethod: 'equals',
    matchValue: SO_GOU_ENCYCLOPEDIA_HOSTNAME,
    convertTo: SO_GOU_HOSTNAME,
  },
  // 360 搜索
  {
    matchMethod: 'equals',
    matchValue: SO_AI_HOSTNAME,
    convertTo: SO_HOSTNAME,
  },
  {
    matchMethod: 'equals',
    matchValue: SO_VIDEO_HOSTNAME,
    convertTo: SO_HOSTNAME,
  },
  {
    matchMethod: 'equals',
    matchValue: SO_NEWS_HOSTNAME,
    convertTo: SO_HOSTNAME,
  },
  {
    matchMethod: 'equals',
    matchValue: SO_WEN_KU_HOSTNAME,
    convertTo: SO_HOSTNAME,
  },
  {
    matchMethod: 'equals',
    matchValue: SO_ENCYCLOPEDIA_HOSTNAME,
    convertTo: SO_HOSTNAME,
  },
]

/**
 * 应用域名转换规则后的域名
 */
export const HOSTNAME: string = (() => {
  // 处理非浏览器环境（如SSR）
  if (typeof window === 'undefined') {
    return ''
  }

  // 应用转换规则
  return applyConvertRules(getCurrentHostname(), HOSTNAME_CONVERT_RULES)
})()

/**
 * 应用域名转换规则
 * @param hostname 原始域名
 * @param rules 转换规则
 * @returns 转换后的域名
 */
function applyConvertRules(hostname: string, rules: HostnameConvertRule[]): string {
  for (const rule of rules) {
    try {
      let matched = false

      switch (rule.matchMethod) {
        case 'equals':
          matched = hostname === rule.matchValue
          break
        case 'startsWith':
          matched = hostname.startsWith(rule.matchValue)
          break
        case 'endsWith':
          matched = hostname.endsWith(rule.matchValue)
          break
        case 'includes':
          matched = hostname.includes(rule.matchValue)
          break
        case 'regex':
          matched = new RegExp(rule.matchValue).test(hostname)
          break
        default:
          console.warn(`未知域名转换规则匹配方法: ${rule.matchMethod}`)
      }

      if (matched) {
        return rule.convertTo
      }
    }
    catch (error) {
      console.error(`域名转换规则应用错误:`, rule, error)
    }
  }

  return hostname
}
